package com.yunhe.authority.service.authority.impl;

import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.yunhe.authority.domain.authority.RealStation;
import com.yunhe.authority.domain.authority.Station;
import com.yunhe.authority.domain.company.Company;
import com.yunhe.authority.domain.office.Office;
import com.yunhe.authority.model.RealStationOfficeVo;
import com.yunhe.authority.model.RealStationVo;
import com.yunhe.authority.model.inspect.RealStationOfficeCompanyVo;
import com.yunhe.authority.repository.authority.RealStationRepository;
import com.yunhe.authority.repository.company.CompanyCrudRepository;
import com.yunhe.authority.repository.company.CompanyRepository;
import com.yunhe.authority.service.authority.RealStationService;
import com.yunhe.authority.service.authority.StationService;
import com.yunhe.authority.service.base.SerialNumService;
import com.yunhe.authority.service.office.OfficeService;
import com.yunhe.common.constant.OfficeConts;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.filter.ServerContextHolder;
import com.yunhe.common.util.CollectionUtil;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author zhengbo
 * @date 2021/5/11 16:32
 */
@Service
public class RealStationServiceImpl implements RealStationService {

    @Autowired
    private RealStationRepository realStationRepository;

    @Autowired
    private OfficeService officeService;

    @Autowired
    private CompanyRepository companyRepository;

    @Autowired
    private CompanyCrudRepository companyCrudRepository;

    @Autowired
    private SerialNumService serialNumService;

    @Autowired
    private StationService stationService;

    @Override
    public RealStation findById(Long id) {
        RealStation realStation = realStationRepository.findById(id).orElse(null);
        return realStation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public synchronized RealStation creatRealStation(Long stationId, RealStation realStation) throws PinyinException, UniqueConstraintsException {

        if (StringUtils.isNotEmpty(realStation.getTitle())) {
            RealStation existRealStation = realStationRepository.findRealStationByStationIdAndTitle(stationId, realStation.getTitle());
            if (existRealStation != null) {
                throw new UniqueConstraintsException(realStation.getTitle() + "已存在");
            }
        }
        //园区简称
        if (StringUtils.isNotEmpty(realStation.getAbbreviationName())) {
            RealStation existRealStation = realStationRepository.findRealStationByStationIdAndAbbreviationName(stationId, realStation.getAbbreviationName());
            if (existRealStation != null) {
                throw new UniqueConstraintsException(realStation.getAbbreviationName() + "已存在");
            }
        }
        //园区全称
        if (StringUtils.isNotEmpty(realStation.getEnterpriseFullName())) {
            RealStation existRealStation = realStationRepository.findRealStationByStationIdAndEnterpriseFullName(stationId, realStation.getEnterpriseFullName());
            if (existRealStation != null) {
                throw new UniqueConstraintsException(realStation.getEnterpriseFullName() + "已存在");
            }
        }


        String yq = serialNumService.generateSerialNumberByModelCode("rp");
        realStation.setName(yq);
        realStation.setSn(PinyinHelper.getShortPinyin(realStation.getEnterpriseFullName()).toUpperCase());
        realStation.setCreateTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(),new Date()));
        RealStation newRealStation = realStationRepository.save(realStation);
        realStationRepository.realStationBindStation(newRealStation.getId(), stationId);
        return newRealStation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public RealStation update(RealStation realStation) throws ObjectNotFoundException, UniqueConstraintsException {
        Optional<RealStation> optionalRealStation = realStationRepository.findById(realStation.getId());
        if (!optionalRealStation.isPresent()) {
            throw new ObjectNotFoundException("未找到名为" + realStation.getEnterpriseFullName() +"的真实园区");
        }
        Station station = stationService.findStationByRealStationId(realStation.getId());
        if(station == null){
            throw new ObjectNotFoundException("真实园区对应的的项目未找到");
        }
        //园区简称
        if (StringUtils.isNotEmpty(realStation.getAbbreviationName())) {
            RealStation existRealStation = realStationRepository.findRealStationByStationIdAndAbbreviationName(station.getId(), realStation.getAbbreviationName());
            if (existRealStation != null && realStation.getId().longValue() != existRealStation.getId().longValue()) {
                throw new UniqueConstraintsException(realStation.getAbbreviationName() + "已存在");
            }
        }
        //园区全称
        if (StringUtils.isNotEmpty(realStation.getEnterpriseFullName())) {
            RealStation existRealStation = realStationRepository.findRealStationByStationIdAndEnterpriseFullName(station.getId(), realStation.getEnterpriseFullName());
            if (existRealStation != null && realStation.getId().longValue() != existRealStation.getId().longValue()) {
                throw new UniqueConstraintsException(realStation.getEnterpriseFullName() + "已存在");
            }
        }
        RealStation oldRealStation = optionalRealStation.get();
        Optional.ofNullable(realStation.getAbbreviationName()).ifPresent(oldRealStation::setAbbreviationName);
        Optional.ofNullable(realStation.getName()).ifPresent(oldRealStation::setName);
        Optional.ofNullable(realStation.getTitle()).ifPresent(oldRealStation::setTitle);
        Optional.ofNullable(realStation.getAddress()).ifPresent(oldRealStation::setAddress);
        Optional.ofNullable(realStation.getArea()).ifPresent(oldRealStation::setArea);
        Optional.ofNullable(realStation.getAreaAddress()).ifPresent(oldRealStation::setAreaAddress);
        Optional.ofNullable(realStation.getAreaAddressTitle()).ifPresent(oldRealStation::setAreaAddressTitle);
        Optional.ofNullable(realStation.getBusinessRegisteredAddress()).ifPresent(oldRealStation::setBusinessRegisteredAddress);
        Optional.ofNullable(realStation.getCategory()).ifPresent(oldRealStation::setCategory);
        Optional.ofNullable(realStation.getCategoryTitle()).ifPresent(oldRealStation::setCategoryTitle);
        Optional.ofNullable(realStation.getContactPerson()).ifPresent(oldRealStation::setContactPerson);
        Optional.ofNullable(realStation.getContactTitle()).ifPresent(oldRealStation::setContactTitle);
        Optional.ofNullable(realStation.getCorporateLogo()).ifPresent(oldRealStation::setCorporateLogo);
        Optional.ofNullable(realStation.getCorporateLogoThumbnail()).ifPresent(oldRealStation::setCorporateLogoThumbnail);
        Optional.ofNullable(realStation.getCorporateName()).ifPresent(oldRealStation::setCorporateName);
        Optional.ofNullable(realStation.getEnterpriseFullName()).ifPresent(oldRealStation::setEnterpriseFullName);
        Optional.ofNullable(realStation.getFormerName()).ifPresent(oldRealStation::setFormerName);
        Optional.ofNullable(realStation.getLatitude()).ifPresent(oldRealStation::setLatitude);
        Optional.ofNullable(realStation.getLongitude()).ifPresent(oldRealStation::setLongitude);
        Optional.ofNullable(realStation.getOperatingPeriod()).ifPresent(oldRealStation::setOperatingPeriod);
        Optional.ofNullable(realStation.getPhone()).ifPresent(oldRealStation::setPhone);
        Optional.ofNullable(realStation.getPhotovoltaicCapacity()).ifPresent(oldRealStation::setPhotovoltaicCapacity);
        Optional.ofNullable(realStation.getProductionTime()).ifPresent(oldRealStation::setProductionTime);
        Optional.ofNullable(realStation.getRegisteredCapital()).ifPresent(oldRealStation::setRegisteredCapital);
        Optional.ofNullable(realStation.getSchematicDiagramBase64()).ifPresent(oldRealStation::setSchematicDiagramBase64);
        Optional.ofNullable(realStation.getSn()).ifPresent(oldRealStation::setSn);
        Optional.ofNullable(realStation.getStationType()).ifPresent(oldRealStation::setStationType);
        Optional.ofNullable(realStation.getStorageCapacity()).ifPresent(oldRealStation::setStorageCapacity);
        Optional.ofNullable(realStation.getSystem()).ifPresent(oldRealStation::setSystem);
        Optional.ofNullable(realStation.getSystemTitle()).ifPresent(oldRealStation::setSystemTitle);
        Optional.ofNullable(realStation.getUnifiedSocialCreditCode()).ifPresent(oldRealStation::setUnifiedSocialCreditCode);
        Optional.ofNullable(realStation.getWindCapacity()).ifPresent(oldRealStation::setWindCapacity);
        return realStationRepository.save(oldRealStation);
    }

    @Override
    public RealStation findByTitle(Long stationId, String title) {
        return realStationRepository.findByTitle(stationId, title);
    }

    @Override
    public RealStation findRealStationByStationIdAndTitle(Long stationId, String title) {
        return realStationRepository.findRealStationByStationIdAndEnterpriseFullName(stationId, title);
    }

    @Override
    public RealStation findRealStationByStationIdAndAbbreviationName(Long stationId, String abbreviationName) {
        return realStationRepository.findRealStationByStationIdAndAbbreviationName(stationId, abbreviationName);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void deleteById(Long id) {
        //这边要删除真实园区绑定的厂房
        Iterable<Office> offices = officeService.findOfficesByRealStationId(id);
        if (offices.iterator().hasNext()) {
            offices.forEach(office -> {
                try {
                    officeService.deleteById(office.getId());
                } catch (ArgumentErrorException e) {
                    e.printStackTrace();
                }
            });
        }

        //这边要删除真实园区绑定的企业
        Iterable<Company> companies = companyRepository.findListCompaniesByRealStationId(id);
        if (companies.iterator().hasNext()) {
            companies.forEach(company -> companyCrudRepository.delete(company));
        }

        realStationRepository.deleteById(id);
    }

    @Override
    public Iterable<RealStation> findRealStationByStationId(Long stationId) {
        return realStationRepository.findRealStationByStationId(stationId);
    }

    @Override
    public Iterable<RealStation> searchStationAndOfficeByStationId(Long stationId) {
        Iterable<RealStation> realStations = realStationRepository.findRealStationByStationId(stationId);
        realStations.forEach(realStation -> {
            Iterable<Office> offices = officeService.findOfficesByRealStationId(realStation.getId());
            if(offices != null){
                List<Office> offices1 = new ArrayList<>();
                for (Office office : offices) {
                    if(OfficeConts.OFFICE_STATUS_CODE.Vacant.value().equals(office.getOfficeStatus()) || "1".equals(office.getStatusFlag())){
                        office.setDisabled(false);

                    }else {
                        office.setDisabled(true);
                    }
                    offices1.add(office);
                }
                if(CollectionUtil.isNotEmpty(offices1)){
                    realStation.setDisabled(false);
                }else {
                    realStation.setDisabled(true);
                }
                realStation.setOfficeList(offices1);
            }else {
                realStation.setDisabled(true);
            }

        });
        return realStations;
    }

    @Override
    public void realStationBindOffice(Long id, Long officeId) {
        realStationRepository.realStationBindOffice(id, officeId);
    }

    @Override
    public void realStationBindCompany(Long id, Long companyId) {
        realStationRepository.realStationBindCompany(id, companyId);
    }

    @Override
    public RealStation findRealStationByOfficeId(Long officeId) {
        return realStationRepository.findRealStationByOfficeId(officeId);
    }

    @Override
    public RealStation findRealStationByCompanyId(Long companyId) {
        return realStationRepository.findRealStationByCompanyId(companyId);
    }

    @Override
    public RealStation searchById(Long id) {
        return realStationRepository.findById(id).orElse(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void unbindOfficeByOfficeId(Long officeId) {
        realStationRepository.unbindOfficeByOfficeId(officeId);
    }

    @Override
    public Iterable<RealStation> findAll() {
        return realStationRepository.findAll();
    }

    @Override
    public List<RealStationVo> searchRealStationByStationId(Long stationId) {
        List<RealStationVo> realStationVos = new ArrayList<>();
        Iterable<RealStation> realStations = realStationRepository.findRealStationByStationId(stationId);
        realStations.forEach(realStation -> {
            RealStationVo realStationVo = new RealStationVo();
            realStationVo.setCode(String.valueOf(realStation.getId()));
            realStationVo.setType("realStation");
            realStationVo.setName(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
            realStationVo.setId(realStation.getId());
            realStationVos.add(realStationVo);
        });
        return realStationVos;
    }

    @Override
    public RealStationOfficeVo searchRealStationAndOffice() {
        RealStationOfficeVo realStationOfficeVo = new RealStationOfficeVo();
        realStationOfficeVo.setTitle("全部");
        realStationOfficeVo.setKey("00");
        realStationOfficeVo.setValue("00");
        String projectCode = ServerContextHolder.getContext().getProjectCode();
        if(!StringUtil.isEmpty(projectCode)){
            Iterable<RealStation> realStations = realStationRepository.findRealStationByStationId(Long.valueOf(projectCode));
            List<RealStationOfficeVo> realStationOfficeVos = new ArrayList<>();
            realStations.forEach(realStation -> {
                RealStationOfficeVo realStationOfficeVo1 = new RealStationOfficeVo();
                realStationOfficeVo1.setTitle(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
                realStationOfficeVo1.setKey(String.valueOf(realStation.getId()));
                realStationOfficeVo1.setValue(String.valueOf(realStation.getId()));
                realStationOfficeVos.add(realStationOfficeVo1);
                //查询已租或已售厂房信息
                Iterable<Office> offices = officeService.findOfficesByRealStationId(realStation.getId());
                List<RealStationOfficeVo> officeVos = new ArrayList<>();
                offices.forEach(office -> {
                    if(OfficeConts.OFFICE_STATUS_CODE.Rented.value().equals(office.getOfficeStatus()) ||
                            OfficeConts.OFFICE_STATUS_CODE.Sold.value().equals(office.getOfficeStatus())){
                        RealStationOfficeVo realStationOfficeVo2 = new RealStationOfficeVo();
                        realStationOfficeVo2.setTitle(office.getOfficeTitle());
                        realStationOfficeVo2.setKey(realStation.getId()+"-"+office.getId());
                        realStationOfficeVo2.setValue(realStation.getId()+"-"+office.getId());
                        officeVos.add(realStationOfficeVo2);
                    }
                });
                realStationOfficeVo1.setChildren(officeVos);
            });
            realStationOfficeVo.setChildren(realStationOfficeVos);
        }
        return realStationOfficeVo;
    }

    @Override
    public List<RealStationOfficeCompanyVo> searchStationAndOfficeAndCompanyByStationId(Long stationId) {
        List<RealStationOfficeCompanyVo> realStationOfficeCompanyVos = new ArrayList<>();
        Iterable<RealStation> realStations = realStationRepository.findRealStationByStationId(stationId);
        if(realStations != null){
            realStations.forEach(realStation -> {
                //查询已租或已售厂房信息
                Iterable<Office> offices = officeService.findOfficesByRealStationId(realStation.getId());
                offices.forEach(office -> {
                    if(OfficeConts.OFFICE_STATUS_CODE.Rented.value().equals(office.getOfficeStatus()) ||
                            OfficeConts.OFFICE_STATUS_CODE.Sold.value().equals(office.getOfficeStatus())){
                        RealStationOfficeCompanyVo realStationOfficeCompanyVo = new RealStationOfficeCompanyVo();
                        //查询对应房源信息的企业信息
                        Company company = companyCrudRepository.findByOfficeId(office.getId());
                        if(company != null){
                            realStationOfficeCompanyVo.setRealStationId(realStation.getId());
                            realStationOfficeCompanyVo.setRealStationName(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
                            realStationOfficeCompanyVo.setCompanyId(company.getId());
                            realStationOfficeCompanyVo.setCompanyTitle(company.getTitle());
                            realStationOfficeCompanyVo.setOfficeId(office.getId());
                            realStationOfficeCompanyVo.setOfficeTitle(office.getOfficeTitle());
                            realStationOfficeCompanyVos.add(realStationOfficeCompanyVo);
                        }
                    }
                });
            });
        }
        return realStationOfficeCompanyVos;
    }

    @Override
    public List<RealStationOfficeCompanyVo> searchStationAndOfficeAndCompany(List<String> values) {
        List<RealStationOfficeCompanyVo> realStationOfficeCompanyVos = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(values)){
            for (String value : values) {
                String[] split = value.split("-");
                RealStation realStation = findById(Long.valueOf(split[0]));
                if(split.length >1){
                    RealStationOfficeCompanyVo realStationOfficeCompanyVo = new RealStationOfficeCompanyVo();
                    //查询厂房信息以及企业信息
                    Office office = officeService.findById(Long.valueOf(split[1]));
                    //查询对应房源信息的企业信息
                    Company company = companyCrudRepository.findByOfficeId(Long.valueOf(split[1]));
                    realStationOfficeCompanyVo.setRealStationId(realStation.getId());
                    realStationOfficeCompanyVo.setRealStationName(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
                    realStationOfficeCompanyVo.setCompanyId(company.getId());
                    realStationOfficeCompanyVo.setCompanyTitle(company.getTitle());
                    realStationOfficeCompanyVo.setOfficeId(office.getId());
                    realStationOfficeCompanyVo.setOfficeTitle(office.getOfficeTitle());
                    realStationOfficeCompanyVos.add(realStationOfficeCompanyVo);
                }else {
                    //查询园区下已租或已售厂房信息
                    Iterable<Office> offices = officeService.findOfficesByRealStationId(realStation.getId());
                    offices.forEach(office -> {
                        if(OfficeConts.OFFICE_STATUS_CODE.Rented.value().equals(office.getOfficeStatus()) ||
                                OfficeConts.OFFICE_STATUS_CODE.Sold.value().equals(office.getOfficeStatus())){
                            RealStationOfficeCompanyVo realStationOfficeCompanyVo = new RealStationOfficeCompanyVo();
                            //查询对应房源信息的企业信息
                            Company company = companyCrudRepository.findByOfficeId(office.getId());
                            if(company != null){
                                realStationOfficeCompanyVo.setRealStationName(StringUtil.isEmpty(realStation.getAbbreviationName())?realStation.getEnterpriseFullName():realStation.getAbbreviationName());
                                realStationOfficeCompanyVo.setRealStationId(realStation.getId());
                                realStationOfficeCompanyVo.setCompanyId(company.getId());
                                realStationOfficeCompanyVo.setCompanyTitle(company.getTitle());
                                realStationOfficeCompanyVo.setOfficeId(office.getId());
                                realStationOfficeCompanyVo.setOfficeTitle(office.getOfficeTitle());
                                realStationOfficeCompanyVos.add(realStationOfficeCompanyVo);
                            }
                        }
                    });
                }
            }
        }
        return realStationOfficeCompanyVos;
    }
}
